#include	"alp_global_vars.h"
#include 	"config_parser.h"

char proposerID_char[STRING_SIZE];

//------------------------------------------------------------------------------
void p_initialize() {
	sprintf(proposerID_char, "%d", get_config_info()->self_proposer_id);

}
//------------------------------------------------------------------------------
int generate_unique_id() {
	int temp;
	char stringTemp[STRING_SIZE];
	digit++;
	temp = digit * 10;
	sprintf(stringTemp, "%d", temp);
	int new_msg_id = atoi(strcat(stringTemp, proposerID_char));
	return new_msg_id;

}
//------------------------------------------------------------------------------
void send_proposer_msg_to_successor(int next_index_to_proposer) {

	p_msgs[get_config_info()->self_acceptor_id][next_index_to_proposer].mili_seconds = getMiliSeconds();
	int status = send((get_config_info()->server_infos[get_config_info()->self_acceptor_id].successor_sid), &(p_msgs[get_config_info()->self_acceptor_id][next_index_to_proposer]), sizeof(proposer_msg), MSG_WAITALL);
	//	printf("%d\n", status);
	assert(status == sizeof(proposer_msg));

}
//------------------------------------------------------------------------------
void produce_msg() {
	p_msgs[get_config_info()->self_acceptor_id][(alp_interval_performance->next_location_index_in_proposer) % INTERNAL_BUFFER_SIZE].type = 'p';
	p_msgs[get_config_info()->self_acceptor_id][(alp_interval_performance->next_location_index_in_proposer) % INTERNAL_BUFFER_SIZE].msg_id = generate_unique_id();
	p_msgs[get_config_info()->self_acceptor_id][(alp_interval_performance->next_location_index_in_proposer) % INTERNAL_BUFFER_SIZE].proposer_id = get_config_info()->self_proposer_id;
	p_msgs[get_config_info()->self_acceptor_id][(alp_interval_performance->next_location_index_in_proposer) % INTERNAL_BUFFER_SIZE].highest_deliverable_inst_id = alp_interval_performance->highest_deliverable_inst_id;
	p_msgs[get_config_info()->self_acceptor_id][(alp_interval_performance->next_location_index_in_proposer) % INTERNAL_BUFFER_SIZE].location_index_in_proposer = alp_interval_performance->next_location_index_in_proposer;
	p_msgs[get_config_info()->self_acceptor_id][(alp_interval_performance->next_location_index_in_proposer) % INTERNAL_BUFFER_SIZE].final_decision = -1;

}
//------------------------------------------------------------------------------
void generate_proposer_msg_timer_event(int sd, short event, void * arg) {

	UNUSED_ARG(sd);
	UNUSED_ARG(event);
	UNUSED_ARG(arg);

	int pmsg_counter = 0;
	alp_interval_performance->interval_num_entrance++;
	learner_deliver();

	while (pmsg_counter < PROP_PER_WAKE) {

		if ((alp_interval_performance->next_location_index_in_proposer) < (INTERNAL_BUFFER_SIZE + (alp_interval_performance->highest_self_deliverable) - 1)) {
			if (get_config_info()->self_proposer_id == 0) {
				if (alp_interval_performance->next_instance_id < (INTERNAL_BUFFER_SIZE * get_config_info()->total_num_proposers)+ alp_interval_performance->highest_deliverable_inst_id - 1) {
					produce_msg();
					p_msgs[get_config_info()->self_acceptor_id][(alp_interval_performance->next_location_index_in_proposer) % INTERNAL_BUFFER_SIZE].num_nodes_visited = 0;
					p_msgs[get_config_info()->self_acceptor_id][(alp_interval_performance->next_location_index_in_proposer) % INTERNAL_BUFFER_SIZE].mili_seconds = getMiliSeconds();
					generate_instance(&p_msgs[get_config_info()->self_acceptor_id][(alp_interval_performance->next_location_index_in_proposer) % INTERNAL_BUFFER_SIZE]);

				} else
					break;
			} else {
				produce_msg();
				p_msgs[get_config_info()->self_acceptor_id][(alp_interval_performance->next_location_index_in_proposer) % INTERNAL_BUFFER_SIZE].num_nodes_visited = 1;
				send_proposer_msg_to_successor((alp_interval_performance->next_location_index_in_proposer) % INTERNAL_BUFFER_SIZE);

			}

			//			if (get_config_info()->self_acceptor_id != 0) {
			//
			//			} else {
			//			}

			alp_interval_performance->interval_bytes_proposed += sizeof(proposer_msg) - PROPOSER_MSG_HEADER;
			alp_interval_performance->interval_num_packets_proposed++;
			alp_interval_performance->total_num_packets_proposed++;
			alp_interval_performance->next_location_index_in_proposer++;
			pmsg_counter++;
		} else
			break;

	}
	evtimer_add(proposal_propose_timeout_eve, &tv2);
}

